package cn.px.hro.statement.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;

import cn.px.common.core.domain.AjaxResult;
import cn.px.common.utils.DateUtils;
import cn.px.common.utils.SecurityUtils;
import cn.px.common.utils.SnowflakeIdWorker;
import cn.px.hro.common.enums.HroEnum;
import cn.px.hro.statement.domain.HroStatementInsureCost;
import cn.px.hro.statement_detail.mapper.HroStatementDetailMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.px.hro.statement.mapper.HroStatementMapper;
import cn.px.hro.statement.domain.HroStatement;
import cn.px.hro.statement.service.IHroStatementService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.AlternativeJdkIdGenerator;
import org.springframework.util.IdGenerator;

/**
 * 结算单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-06-10
 */
@Service
public class HroStatementServiceImpl implements IHroStatementService {
    @Autowired
    private HroStatementMapper hroStatementMapper;
    @Autowired
    private HroStatementDetailMapper hroStatementDetailMapper;

    /**
     * 查询结算单
     *
     * @param id 结算单主键
     * @return 结算单
     */
    @Override
    public HroStatement selectHroStatementById(Long id) {
        return hroStatementMapper.selectHroStatementById(id);
    }

    /**
     * 查询结算单列表
     *
     * @param hroStatement 结算单
     * @return 结算单
     */
    @Override
    public List<HroStatement> selectHroStatementList(HroStatement hroStatement) {
        return hroStatementMapper.selectHroStatementList(hroStatement);
    }

    @Override
    public List<HroStatement> selectHroStatementListJoInFinanAcount(HroStatement hroStatement) {
        return hroStatementMapper.selectHroStatementListJoInFinanAcount(hroStatement);
    }

    /**
     * 新增结算单
     *
     * @param hroStatement 结算单
     * @return 结果
     */
    @Override
    public int insertHroStatement(HroStatement hroStatement) {
        SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0);
        long id = idWorker.nextId();
        hroStatement.setCode("JS-" + id);
        hroStatement.setCreateTime(DateUtils.getNowDate());
        hroStatement.setCreateBy(SecurityUtils.getUsername());
        return hroStatementMapper.insertHroStatement(hroStatement);
    }

    /**
     * 修改结算单
     *
     * @param hroStatement 结算单
     * @return 结果
     */
    @Override
    public int updateHroStatement(HroStatement hroStatement) {
        hroStatement.setUpdateTime(DateUtils.getNowDate());
        return hroStatementMapper.updateHroStatement(hroStatement);
    }

    /**
     * 批量删除结算单
     *
     * @param ids 需要删除的结算单主键
     * @return 结果
     */
    @Override
    public int deleteHroStatementByIds(Long[] ids) {
        return hroStatementMapper.deleteHroStatementByIds(ids);
    }

    /**
     * 删除结算单信息
     *
     * @param id 结算单主键
     * @return 结果
     */
    @Override
    public int deleteHroStatementById(Long id) {
        return hroStatementMapper.deleteHroStatementById(id);
    }

    @Override
    public List<HroStatement> getTotalMoneyByMonth(Map<String, Object> map) {
        return hroStatementMapper.getTotalMoneyByMonth(map);
    }

    @Override
    public int editTotalAmount(HroStatement hroStatement) {
        BigDecimal shouldTotalAmount = hroStatement.getShouldTotalAmount();
        BigDecimal shouldTotalAmountNew = hroStatement.getShouldTotalAmountNew();
        String editAmountReason = hroStatement.getEditAmountReason() == null ? "" : hroStatement.getEditAmountReason();
        String editAmountReasonNew = hroStatement.getEditAmountReasonNew();
        Long id = hroStatement.getId();
        HroStatement hroStatementExist = hroStatementMapper.selectHroStatementById(id);
        BigDecimal returnAmount = hroStatementExist.getReturnAmount();
        String newReasonString = "原金额：" + shouldTotalAmount + "，现金额：" + shouldTotalAmountNew + "，修改原因：" + editAmountReasonNew + "；";
        HroStatement hroStatementUpdate = new HroStatement();
        hroStatementUpdate.setId(id);
        hroStatementUpdate.setShouldTotalAmount(shouldTotalAmountNew);
        hroStatementUpdate.setNotRcvAmount(shouldTotalAmountNew.subtract(returnAmount));
        hroStatementUpdate.setEditAmountReason(editAmountReason + newReasonString);
        return updateHroStatement(hroStatementUpdate);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long updateStatementAmount(HroStatement hroStatementSelect, boolean isUpdate) {
        String taxType = hroStatementSelect.getCompanyAgreement().getTaxType();
        BigDecimal taxNot = hroStatementSelect.getCompanyAgreement().getTax();
        BigDecimal tax = taxNot.divide(new BigDecimal(100));
        BigDecimal returnAmount = hroStatementSelect.getReturnAmount() == null ? BigDecimal.ZERO : hroStatementSelect.getReturnAmount();
        BigDecimal salary = hroStatementSelect.getSalary() == null ? BigDecimal.ZERO : hroStatementSelect.getSalary();
        BigDecimal socialSecurityAmount = hroStatementSelect.getSocialSecurityAmount() == null ? BigDecimal.ZERO : hroStatementSelect.getSocialSecurityAmount();
        BigDecimal accFundAmount = hroStatementSelect.getAccFundAmount() == null ? BigDecimal.ZERO : hroStatementSelect.getAccFundAmount();
        BigDecimal serverAmount1 = hroStatementSelect.getServerAmount();
        BigDecimal multiply = BigDecimal.ZERO;
        if (HroEnum.AGREEMENT_TAX_TYPE_1.getCode().equals(taxType)) {
            multiply = salary.multiply(tax).setScale(2, RoundingMode.HALF_UP);
        } else if (HroEnum.AGREEMENT_TAX_TYPE_2.getCode().equals(taxType)) {
            BigDecimal add = salary.add(serverAmount1);
            multiply = add.multiply(tax).setScale(2, RoundingMode.HALF_UP);
        }
        BigDecimal add = serverAmount1.add(salary).add(socialSecurityAmount).add(accFundAmount).add(multiply);
        BigDecimal subtract = add.subtract(returnAmount);
        hroStatementSelect.setShouldTotalAmount(add);
        hroStatementSelect.setNotRcvAmount(subtract);
        if (isUpdate) {
            int i = updateHroStatement(hroStatementSelect);
            return (long) i;
        } else {
            insertHroStatement(hroStatementSelect);
            return hroStatementSelect.getId();
        }
    }

    @Override
    public HroStatementInsureCost getInsureCostInfo(Long id) {
        return hroStatementMapper.selectStatementInsureCostById(id);
    }

    @Override
    public List<HroStatement> selectStatementListByIds(Long[] ids){
        return hroStatementMapper.selectStatementListByIds(ids);
    }
}
